import { useState, useMemo } from 'react';
import {
  DndContext,
  DragOverlay,
  KeyboardSensor,
  PointerSensor,
  useSensor,
  useSensors,
  rectIntersection,
  closestCenter,
  pointerWithin,
  closestCorners,
  MeasuringStrategy
} from '@dnd-kit/core';
import {
  arrayMove,
  SortableContext,
  sortableKeyboardCoordinates,
  verticalListSortingStrategy,
} from '@dnd-kit/sortable';
import { useSortable } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { restrictToVerticalAxis } from '@dnd-kit/modifiers';
import './index.less'
import classNames from 'classnames';
import { RightOutlined } from '@ant-design/icons';

// 辅助函数：根据ID查找项目
const findItemById = (items, id) => {
  const stack = [...items];
  while (stack.length) {
    const item = stack.pop();
    if (item.nodeId === id) return item;
    if (item.columns) stack.push(...item.columns);
    if (item.children) stack.push(...item.children);
  }
  return null;
};


// 修复类型错误的碰撞检测函数
const customCollisionDetection = (args) => {
  const { active, collisionRect, droppableContainers } = args;
  // 获取当前拖动元素的父元素 ID
  const activeParentId = active.data.current?.parentId;
  const activeDepth = active.data.current?.depth;

  // 过滤掉父元素是 B 的容器
  const filteredContainers = droppableContainers.filter((container) => {
    if (activeDepth !== 2) return true;
    const activeAnId = activeParentId.split('-')[0]
    return !activeParentId || container.id !== activeAnId && container.id !== activeParentId;
  });
  console.log(filteredContainers);
  // 如果没有直接命中，则使用closestCorners
  return rectIntersection({
    ...args,
    droppableContainers: filteredContainers
  });
}
// 辅助函数：查找项目及其父级信息
const findItemWithParent = (items, id) => {
  const find = (items, path: any[] = []) => {
    for (let i = 0; i < items.length; i++) {
      const item = items[i];
      if (item.nodeId === id) return { item, path };

      let children = [];
      if (item.type === 'container') children = item.columns || [];
      if (item.type === 'column') children = item.children || [];

      const result = find(children, [...path, { item, index: i }]);
      if (result) return result;
    }
    return null;
  };

  return find(items);
};

// 辅助函数：检查祖先关系
const isAncestor = (items, ancestorId, descendantId) => {
  let currentId = descendantId;
  while (currentId) {
    const result = findItemWithParent(items, currentId);
    if (!result) return false;
    if (result.path.some(p => p.item.nodeId === ancestorId)) return true;
    currentId = result.path[0]?.item.nodeId;
  }
  return false;
};

// 重新排序逻辑
const reorderItems = (items, activeId, overId) => {
  const activeInfo = findItemWithParent(items, activeId);
  const overInfo = findItemWithParent(items, overId);

  if (!activeInfo || !overInfo) return items;
  if (isAncestor(items, activeId, overId)) return items;

  const newItems = JSON.parse(JSON.stringify(items));

  // 获取实际的位置路径
  const getNestedArray = (path) => {
    return path.reduce((arr, step) => {
      let container = arr[step.index];
      return container?.columns || container?.children || arr;
    }, newItems);
  };

  const activeArray = getNestedArray(activeInfo.path);
  const overArray = getNestedArray(overInfo.path);

  const activeIndex = activeInfo.path[activeInfo.path.length - 1]?.index;
  const overIndex = overInfo.path[overInfo.path.length - 1]?.index;

  // 执行跨数组移动
  if (activeArray !== overArray) {
    const [removed] = activeArray.splice(activeIndex, 1);
    overArray.splice(overIndex, 0, removed);
  } else {
    arrayMove(activeArray, activeIndex, overIndex);
  }

  return newItems;
};

// 拖拽悬浮层组件
const DragOverlayContent = ({ id, items }) => {
  const item = findItemById(items, id);

  if (!item) return null;
  if (item.dragType === 'block') {
    return (
      <div className="tree-node dragging">
        <div className="node-header">
          <span className="drag-handle">⋮⋮</span>
          <div className="node-info">
            <span className="node-type">{item.type}</span>
            <span className="node-id">{item.id}</span>
          </div>
        </div>
      </div>
    );
  } else if (item.dragType === 'column') {
    return (
      <div className="column dragging">
        <div className="column-header">
          <span className="drag-handle">⋮⋮</span>
          <span className="column-title">列 {item.id.split('_').pop()}</span>
        </div>
      </div>
    );
  }

  return null;
};

// 树节点组件
const TreeNode = ({ item, isExpanded, toggleExpand, dragOverId, parentId = undefined, depth = 0 }) => {
  const {
    attributes,
    listeners,
    setNodeRef,
    transform,
    transition,
    isDragging,
  } = useSortable({ id: item.nodeId, data: { depth, parentId, item: item } });
  const { columns = [], children = [] } = item;
  const childrenList = columns.length ? columns : children;

  const style: React.CSSProperties = {
    transition: transition || 'transform 150ms cubic-bezier(0.25, 1, 0.5, 1)',
    opacity: isDragging ? 0.6 : 1,
    position: 'relative',
    zIndex: isDragging ? 999 : 'auto'
  };


  // 渲染投影指示器
  const renderDropIndicator = () => {
    if (dragOverId === item.nodeId) {
      return <div className="drop-indicator" />;
    }
    return null;
  };

  return (
    <div
      ref={setNodeRef}
      style={style}
      className={classNames('tree-node', {
        'is-dragging': isDragging,
        'is-expanded': isExpanded,
        [`type-${item.dragType}`]: true,
        'drag-over': dragOverId === item.nodeId
      })}
      data-depth={depth}
      data-drag-type={item.dragType}
    >
      {renderDropIndicator()}
      <div className="node-header">
        <span className="drag-handle" {...attributes} {...listeners}>⋮⋮</span>
        {/* 如果有子元素，显示折叠/展开按钮 */}
        {(childrenList.length > 0) && (
          <button
            className="collapse-btn"
            onClick={() => toggleExpand(item.nodeId)}
          >
            <RightOutlined className='collapse-btn-icon' style={{ rotate: isExpanded ? '90deg' : '0deg' }} />
          </button>
        )}

        {/* 显示节点信息 */}
        <div className="node-info">
          <span className="node-type">{item.type}</span>
          <span className="node-id">{item.id}</span>
        </div>
      </div>

      {isExpanded && childrenList?.length > 0 && (
        <div className="container-content">
          <div className="columns-container">
            {childrenList.map(column => (
              <TreeNode
                key={column.nodeId}
                item={column}
                isExpanded={isExpanded}
                toggleExpand={toggleExpand}
                dragOverId={dragOverId}
                depth={depth + 1}
                parentId={item.nodeId}
              />
            ))}
          </div>
        </div>

      )}
    </div>
  );
};

const cardTypes = ['cards', "funnel", 'chart', 'table', 'search_form']

// 主组件
const App = () => {
  const [items, setItems] = useState([
    {
      type: "search_form",
      id: "search_form_0DSHN",
      nodeId: "search_form_0DSHN",
      dragType: "block",
      nodeIndex: 1
    },
    {
      type: "container",
      columns: [
        {
          children: [
            {
              type: "cards",
              id: "cards_Bq6hH",
              nodeId: "cards_Bq6hH",
              dragType: "block",
              nodeIndex: 3
            },
            {
              type: "funnel",
              id: "funnel_dlykz",
              nodeId: "funnel_dlykz",
              dragType: "block",
              nodeIndex: 4
            }
          ],
          type: "column",
          id: "container_lyQ8Z-column_0",
          dragType: "column",
          nodeId: "container_lyQ8Z-column_0",
          nodeIndex: 1
        },
        {
          children: [
            {
              type: "chart",
              id: "chart_2gj-c",
              nodeId: "chart_2gj-c",
              dragType: "block",
              nodeIndex: 5
            },
            {
              type: "chart",
              id: "chart_Dlztk",
              nodeId: "chart_Dlztk",
              dragType: "block",
              nodeIndex: 6
            }
          ],
          type: "column",
          id: "container_lyQ8Z-column_1",
          dragType: "column",
          nodeId: "container_lyQ8Z-column_1",
          nodeIndex: 2
        }
      ],
      id: "container_lyQ8Z",
      nodeId: "container_lyQ8Z",
      dragType: "block",
      nodeIndex: 2
    },
    // {
    //   type: "container",
    //   columns: [
    //     {
    //       children: [
    //         {
    //           type: "cards",
    //           id: "cards_333",
    //           nodeId: "cards_333",
    //           dragType: "block",
    //           nodeIndex: 5
    //         }
    //       ],
    //       type: "column",
    //       id: "container_3333-column_0",
    //       dragType: "column",
    //       nodeId: "container_3333-column_0",
    //       nodeIndex: 1
    //     },
    //   ],
    //   id: "container_3333",
    //   nodeId: "container_3333",
    //   dragType: "block",
    //   nodeIndex: 3
    // },
    // {
    //   type: "table",
    //   id: "table_GxmzN",
    //   nodeId: "table_GxmzN",
    //   dragType: "block",
    //   nodeIndex: 7
    // }
  ]); // 保持原有的初始化数据
  const [expandedIds, setExpandedIds] = useState<string[]>([]);
  const [activeId, setActiveId] = useState(null);
  const [dragOverId, setDragOverId] = useState(null);

  const sensors = useSensors(
    useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),
    useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })
  );

  // 动态获取可排序项
  const sortableItems = useMemo(() => {
    const flatten = (items) => items.reduce((acc, item) => {
      acc.push(item.nodeId);
      if (item.columns) acc.push(...flatten(item.columns));
      if (item.children) acc.push(...flatten(item.children));
      return acc;
    }, []);
    const newItems = activeId
      ? flatten(items).filter(id => {
        const item = findItemById(items, id);
        const activeItem = findItemById(items, activeId);
        return item.dragType === activeItem?.dragType;
      })
      : [];
    return newItems
  }, [items, activeId]);

  const handleDragStart = ({ active }) => {
    setActiveId(active.id);
  };

  // @ts-ignore
  const handleDragEnd = ({ active, over }) => {
    setActiveId(null);
    setDragOverId(null);
    if (!over || active.id === over.id) return;
    console.log(active.data.current, over.data.current);
    const overParentId = over.data.current.parentId
    const activeParentId = active.data.current.parentId
    const overDepth = over.data.current.depth
    const activeDepth = active.data.current.depth
    const overType = over.data.current.item.type
    const activeType = active.data.current.item.type


    if (overParentId === activeParentId) {
      if (overParentId === undefined) { // 移动前后都是第一级
        setItems((items) => {
          const oldIndex = items.findIndex(v => v.id === active.id);
          const newIndex = items.findIndex(v => v.id === over.id);
          return arrayMove(items, oldIndex, newIndex);
        })
      } else {  // 移动前后都是第二级或第三级
        setItems((items) => {
          const parentNode = findItemById(items, overParentId);
          let key = active.data.current.depth === 1 ? 'columns' : 'children'
          const oldIndex = parentNode[key].findIndex(v => v.id === active.id);
          const newIndex = parentNode[key].findIndex(v => v.id === over.id);
          parentNode[key] = arrayMove(parentNode[key], oldIndex, newIndex);
          return [...items]
        })
      }
    } else if (overType === 'container' && activeType === 'column') {
      setItems((items) => {
        const activeParentNode = items.find(v => v.id === activeParentId);
        const overNode = items.find(v => v.id === over.id);
        const i = activeParentNode!.columns!.findIndex(v => v.id === active.id);
        const [delone] = activeParentNode!.columns!.splice(i, 1);
        overNode!.columns!.push(delone);
        return [...items]
      })
    } else if (cardTypes.includes(activeType)) {
      if (overDepth === 0) {
        // card移动到最外层
        setItems((items) => {
          const activeParentNode = findItemById(items, activeParentId);
          const i = activeParentNode!.children!.findIndex(v => v.id === active.id);
          const [delone] = activeParentNode!.children!.splice(i, 1);
          const overIndex = items.findIndex(v => v.id === over.id);
          items.splice(overIndex, 0, delone);
          return [...items]
        })
      } else if (overDepth === 1 && activeDepth === 0) {
        // card从最外层移动到column,直接拖到column
        setItems((items) => {
          const i = items.findIndex(v => v.id === active.id);
          const [delone] = items.splice(i, 1);
          const overNode = findItemById(items, over.id);
          overNode.children.push(delone)
          return [...items]
        })
      } else if (overDepth === 2 && activeDepth === 2) {
        // card从一个column下移动到其他column下
        setItems((items) => {
          const activeParentNode = findItemById(items, activeParentId);
          const i = activeParentNode!.children!.findIndex(v => v.id === active.id);
          const [delone] = activeParentNode!.children!.splice(i, 1);
          const overParentNode = findItemById(items, overParentId);
          const overIndex = overParentNode.children.findIndex(v => v.id === over.id);
          overParentNode.children.splice(overIndex, 0, delone);
          return [...items]
        })
      } else if (overDepth === 1 && activeDepth === 2) {
        // card从一个column下移动到其他column下,直接拖到column
        setItems((items) => {
          const activeParentNode = findItemById(items, activeParentId);
          const i = activeParentNode!.children!.findIndex(v => v.id === active.id);
          const [delone] = activeParentNode!.children!.splice(i, 1);
          const overNode = findItemById(items, over.id);
          overNode.children.push(delone)
          return [...items]
        })
      } else if (overDepth === 2 && activeDepth === 0) {
        // card从最外层拖到column下
        const i = items.findIndex(v => v.id === active.id);
        const [delone] = items.splice(i, 1);
        const overParentNode = findItemById(items, overParentId);
        const overIndex = overParentNode.children.findIndex(v => v.id === over.id);
        overParentNode.children.splice(overIndex, 0, delone);
        return [...items]
      }
    }
  };

  const handleDragOver = ({ over }) => {
    if (dragOverId === over?.id) return;
    setDragOverId(over?.id || null);
  };

  const toggleExpand = (nodeId) => {
    setExpandedIds(prev =>
      prev.includes(nodeId)
        ? prev.filter(id => id !== nodeId)
        : [...prev, nodeId]
    );
  };

  return (
    <div className="dnd-container">
      <DndContext
        sensors={sensors}
        collisionDetection={rectIntersection}
        modifiers={[]}
        onDragStart={handleDragStart}
        onDragEnd={handleDragEnd}
        onDragOver={handleDragOver}
        measuring={{
          droppable: {
            strategy: MeasuringStrategy.Always // 使用正确的枚举值
          },
        }}
      >
        <SortableContext
          items={sortableItems}
          strategy={verticalListSortingStrategy}
        >
          <div className="tree-root">
            {items.map(item => (
              <TreeNode
                key={item.nodeId}
                item={item}
                isExpanded={expandedIds.includes(item.nodeId)}
                toggleExpand={toggleExpand}
                dragOverId={dragOverId}
                depth={0}
              />
            ))}
          </div>
        </SortableContext>

        <DragOverlay>
          {activeId && <DragOverlayContent id={activeId} items={items} />}
        </DragOverlay>
      </DndContext>
    </div>
  );
};

export default App;